#include <stdint.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h> 
#include <stdlib.h>
#include <assert.h>
#include "app_platform/cntl_info.h"
#include "acaccountdao.h"
#include "c2cplatform/component/dal/dal_set.h"
#include "c2cent/storage/mysqlstorage.h"
#include "c2cplatform/component/dal/db_operator_mysql_set.h"
using namespace c2cplatform::component::dal;
using namespace c2cent::storage;
using namespace erp::acaccount::dao;

CPP_SELF_DEFINE_START
/**
 *  请在这里增加自定义的成员变量和函数及其他内容，否则无法合并代码
 **/
#include "erp/comm/erp_macro_define.h"
#include "erp/comm/erp_errno_define.h"
#include "c2cplatform/library/string/string_helper.h"
#include "erp/comm/erp_yun_define.h"
#include "c2cent/dao/idmaker/idmakerdao_stub4web_allinone.h"
#include "c2cent/storage/resultset.h"
#include "c2cplatform/library/xml/xml_cfg_loader.h"
#include "c2cent/library/log/CWWLog2.h"
using namespace c2cent::library::wtimeelf;
using namespace c2cent::library::wwlog;
using namespace erp::comm;
using namespace c2cplatform::library::string;
using namespace erp::yun::comm;
using namespace c2cent::dao::idmaker;
#define DB_ROLE_NAME_ACAccount      "erp_yun_acaccount"
#define TABLE_NAME_BANKACCOUNT    "T_BankAccount_"
#define TABLE_NAME_ACITEMS    "T_ACItems_"

//银行账户查询ITIL上报对象初始化
CItilGroup CACAccountDao::m_oGetBankAccount(GETBANKACCOUNT_REQ,
		GETBANKACCOUNT_ERR, GETBANKACCOUNT_RSP, GETBANKACCOUNT_DEF);

//银行账户ByIds查询ITIL上报对象初始化
CItilGroup CACAccountDao::m_oGetBankAccountByIds(GETBANKACCOUNT_REQ,
		GETBANKACCOUNT_ERR, GETBANKACCOUNT_RSP, GETBANKACCOUNT_DEF);

//新增更新银行账户信息ITIL上报对象初始化
CItilGroup CACAccountDao::m_oAddAndUpdateBankAccount(GETBANKACCOUNT_REQ,
		GETBANKACCOUNT_ERR, GETBANKACCOUNT_RSP, GETBANKACCOUNT_DEF);

//逻辑删除银行账户信息ITIL上报对象初始化
CItilGroup CACAccountDao::m_oDeleteBankAccount(GETBANKACCOUNT_REQ,
		GETBANKACCOUNT_ERR, GETBANKACCOUNT_RSP, GETBANKACCOUNT_DEF);

//新增更新经营类会计项目信息ITIL上报对象初始化
CItilGroup CACAccountDao::m_oAddAndUpdateACItems(GETACITEMS_REQ,
		GETACITEMS_ERR, GETACITEMS_RSP, GETACITEMS_DEF);

CPP_SELF_DEFINE_END
/**
 *构建函数
 */
CACAccountDao::CACAccountDao(enum DeployMethod method)
{
}

/**
 *析构函数
 */
CACAccountDao::~CACAccountDao()
{
}

/**
 *每一次服务请求时，container都会调用此方法来清空数据
 */
void CACAccountDao::Reset()
{
}

int CACAccountDao::Initialize(IUserDefineCntl* pCntl)
{
	int iRet = 0;
	uint32_t dwLogSwitch = WLOG_OPEN | WLOG_KEY_OPEN | WLOG_ERR_OPEN;
	uint32_t dwCanLogRemote = 0;
	std::string strLogModule = "dao_acaccountdao";

	std::cout << "File:" << __FILE__ << " Complie Date: " << __DATE__ << " "
			<< __TIME__ << std::endl;

	if (CDAL_SET->Initialize() != 0)
	{
		printf("CDAL_SET Init Failed, %s\n", CDAL_SET->getLastErrMsg());
		return -1;
	}

	GetUintConfig(LogSwitch);
	GetStringConfig(LogModule);
	GetUintConfig(CanLogRemote);

	// 初始化日志
	if (C2C_WWLOG->QuickInitForAPP2(strLogModule.c_str(),B2B2CWW_LOG_APP_FILE_PATH, dwCanLogRemote, dwLogSwitch)!= 0)
	{
		std::cerr << "C2C_WWLOG->QuickInitForAPP2 Failed" << std::endl;
		return -1;
	}
	C2C_WW_LOG("C2C_WWLOG->QuickInitForAPP2 OK!");
	return iRet;
}

/**
 *
 *  通过SysNos获取银行账户信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景id，必填   [in]
 *@param Set sysNoList: 银行账户SysNo数组，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param Map bankAccount: 银行账户信息列表  	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CACAccountDao::GetBankAccountBySysNos(const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey, const std::string& strSource,
		uint32_t dwSceneId, const std::set<uint64_t>& setSysNoList,
		const std::string& strInReserve, std::string& strErrmsg,
		std::map<uint64_t, erp::acaccount::ddo::CBankAccountDdo>& mapBankAccount,
		std::string& strOutReserve)
{
	int iRetCode = 0;
	//TODO:业务代码
	uint16_t iSetId = 0;
	m_dwOperatorUin = rCntlInfo.getOperatorUin();
	m_dwSceneId = dwSceneId;
	m_strMachineKey = strMachineKey;
	m_strSource = strSource;
	uint32_t DB_Stock_Code = rCntlInfo.getOperatorUin(); //表ID

	C2C_WW_LOG("GetAReq %s OpUin:%u MachineKey:%s Source:%s SceneId:%u",
			__FUNCTION__, m_dwOperatorUin, strMachineKey.c_str(),
			strSource.c_str(), dwSceneId);

	//打印性能日志的同时进行接口的itil上报
	C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG,__FUNCTION__,&iRetCode,&m_oGetBankAccountByIds);

	//查询SysNo未空，直接返回0
	if (setSysNoList.size() <= 0)
	{
		return 0;
	}

	c2cent::storage::CMySqlStorage oStorage(
			CDAL_SET->GetDBOperator(rCntlInfo.getCmdId(),
					DB_Stock_Code, DB_ROLE_NAME_ACAccount, TABLE_NAME_BANKACCOUNT, iSetId, true));
	std::stringstream ssSql;

	ssSql
			<< "SELECT FBankAccountSysNo,FParentBankAccountSysNo,FBankAccount,FBankAccountName,FBranchBank,";
	ssSql
			<< " FBankType,FComment,FProperty,FStatus,FCreatorSysNo,UNIX_TIMESTAMP(FRowCreatDate) ,FModifierSysNo,UNIX_TIMESTAMP(FRowModifyDate) FROM";
	ssSql << " "
			<< CDAL_SET->GetTableName(iSetId, DB_Stock_Code, DB_ROLE_NAME_ACAccount, TABLE_NAME_BANKACCOUNT).c_str();
	std::stringstream sysNos;

	for (std::set<uint64_t>::iterator it = setSysNoList.begin();
			it != setSysNoList.end(); it++)
	{
		sysNos << *it << ",";
	}
	ssSql << " WHERE FBankAccountSysNo in (" << Trim(sysNos.str(), ',') << ")";

	//排除已经删除的信息
	ssSql << " AND FStatus<>0";

	printf("查询SQL：%s\n", ssSql.str().c_str());

	//记录SQL日志
	C2C_WW_LOG_DEBUG("ExeSql Passed, Sql:%s", ssSql.str().c_str());

	IResultSet& oRs = oStorage.QueryForResultSet(ssSql.str());

	if (!oRs.IsReady()) //db操作错误
	{
		oRs.Close();
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_SELECT_FAILED, "ExeSql Failed, Sql:%s",
				ssSql.str().c_str());
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_SELECT_FAILED,
				"ExeSql Failed, OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				rCntlInfo.getOperatorUin(), strMachineKey.c_str(),
				strSource.c_str(), dwSceneId);
		C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
		return ERR_ERP_COMMON_DB_SELECT_FAILED;
	}

	if (!oRs.First() || oRs.GetRecordCount() == 0) //无记录
	{
		oRs.Close();
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_SELECT_FAILED, "ExeSql Failed, Sql:%s",
				ssSql.str().c_str());
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_QUERY_FAILED,
				"QuerySql not exist, " "OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				rCntlInfo.getOperatorUin(), strMachineKey.c_str(),
				strSource.c_str(), dwSceneId);
		C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
		return ERR_ERP_COMMON_DB_SELECT_FAILED;
	}

	do
	{
		erp::acaccount::ddo::CBankAccountDdo oBankAccountDdo;
		oBankAccountDdo.SetBankAccountSysNo(oRs.GetBigUInt("FBankAccountSysNo"),
				0);
		oBankAccountDdo.SetBankAccount(
				oRs.GetString("FBankAccount") ?
						oRs.GetString("FBankAccount") : "", 0);
		oBankAccountDdo.SetBankAccountName(
				oRs.GetString("FBankAccountName") ?
						oRs.GetString("FBankAccountName") : "", 0);
		oBankAccountDdo.SetBankType(
				oRs.GetString("FBankType") ? oRs.GetString("FBankType") : "",
				0);
		oBankAccountDdo.SetBranchBank(
				oRs.GetString("FBranchBank") ?
						oRs.GetString("FBranchBank") : "", 0);
		oBankAccountDdo.SetComment(
				oRs.GetString("FComment") ? oRs.GetString("FComment") : "", 0);
		oBankAccountDdo.SetModifierSysNo(oRs.GetBigUInt("FModifierSysNo"), 0);
		oBankAccountDdo.SetParentBankAccountSysNo(
				oRs.GetBigUInt("FParentBankAccountSysNo"), 0);
		oBankAccountDdo.SetProperty((uint32_t) oRs.GetUInt("FProperty"), 0);
		oBankAccountDdo.SetRowCreatDate(oRs.GetBigUInt("FRowCreatDate"), 0);
		oBankAccountDdo.SetRowModifyDate(oRs.GetBigUInt("FRowModifyDate"), 0);
		oBankAccountDdo.SetStatus(oRs.GetUInt("FStatus"), 0);

		mapBankAccount[oBankAccountDdo.GetBankAccountSysNo()] = oBankAccountDdo;
	} while (oRs.Next());
	oRs.Close();

	return iRetCode;
}

/**
 *
 *  Filter过滤获取银行账户信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景id，必填   [in]
 *@param BankAccountFilterDdo bankAccountFilter: 过滤器，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param Vector bankAccount: 银行账户信息 列表 	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CACAccountDao::GetBankAccountByFilter(const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey, const std::string& strSource,
		uint32_t dwSceneId,
		const erp::acaccount::ddo::CBankAccountFilterDdo& oBankAccountFilter,
		const std::string& strInReserve, std::string& strErrmsg,
		std::vector<erp::acaccount::ddo::CBankAccountDdo>& vecBankAccount,
		std::string& strOutReserve)
{
	int iRetCode = 0;
	//TODO:业务代码
	uint16_t iSetId = 0;
	m_dwOperatorUin = rCntlInfo.getOperatorUin();
	m_dwSceneId = dwSceneId;
	m_strMachineKey = strMachineKey;
	m_strSource = strSource;

	C2C_WW_LOG("GetAReq %s OpUin:%u MachineKey:%s Source:%s SceneId:%u",
			__FUNCTION__, m_dwOperatorUin, strMachineKey.c_str(),
			strSource.c_str(), dwSceneId);

	//打印性能日志的同时进行接口的itil上报
	C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG,__FUNCTION__,&iRetCode,&m_oGetBankAccount);

	c2cent::storage::CMySqlStorage oStorage(
			CDAL_SET->GetDBOperator(rCntlInfo.getCmdId(),
					rCntlInfo.getOperatorUin(), DB_ROLE_NAME_ACAccount, TABLE_NAME_BANKACCOUNT,iSetId, true));
	std::stringstream ssSql;

	ssSql
			<< "SELECT FBankAccountSysNo,FParentBankAccountSysNo,FBankAccount,FBankAccountName,FBranchBank,";
	ssSql
			<< " FBankType,FComment,FProperty,FStatus,FCreatorSysNo,UNIX_TIMESTAMP(FRowCreatDate) ,FModifierSysNo,UNIX_TIMESTAMP(FRowModifyDate) FROM";
	ssSql << " "
			<< CDAL_SET->GetTableName(iSetId, 0, DB_ROLE_NAME_ACAccount, TABLE_NAME_BANKACCOUNT).c_str();

	//排除已经逻辑删除的数据
	ssSql << " WHERE FStatus<>0 ";

	if (oBankAccountFilter.IsBankAccountNameSet())
	{
		ssSql << " AND FBankAccountName Like '%"
				<< oBankAccountFilter.GetBankAccountName() << "%'";
	}
	if (oBankAccountFilter.IsBankAccountSet())
	{
		ssSql << " AND FBankAccount Like '%"
				<< oBankAccountFilter.GetBankAccountName() << "%'";
	}
	if (oBankAccountFilter.IsBankTypeSet())
	{
		ssSql << " AND FBankType Like '%" << oBankAccountFilter.GetBankType()
				<< "%'";
	}
	if (oBankAccountFilter.IsBranchBankSet())
	{
		ssSql << " AND FBranchBank Like '%"
				<< oBankAccountFilter.GetBranchBank() << "%'";
	}
	if (oBankAccountFilter.IsParentBankAccountSysNoSet())
	{
		ssSql << " FParentBankAccountSysNo="
				<< oBankAccountFilter.GetParentBankAccountSysNo();
	}
	if (oBankAccountFilter.IsSysNoListSet())
	{
		std::stringstream sysNos;

		for (std::set<uint64_t>::iterator it =
				oBankAccountFilter.setSysNoList.begin();
				it != oBankAccountFilter.setSysNoList.end(); it++)
		{
			sysNos << *it << ",";
		}
		ssSql << " WHERE FBankAccountSysNo in (" << Trim(sysNos.str(), ',')
				<< ")";
	}

	//属性查询
	if (oBankAccountFilter.IsPropertyIncludeSet())
	{

		if (oBankAccountFilter.GetPropertyOption() == 1)
		{
			ssSql << " FBankAccountSysNo&"
					<< (oBankAccountFilter.GetPropertyInclude()).to_ulong();
		}
		else
		{
			ssSql << " ~FBankAccountSysNo" << "&"
					<< (oBankAccountFilter.GetPropertyInclude()).to_ulong()
					<< "^"
					<< (oBankAccountFilter.GetPropertyInclude()).to_ulong();
		}
	}
	if (oBankAccountFilter.IsPropertyExcludeSet())
	{

		ssSql << " ~FBankAccountSysNo&"
				<< (oBankAccountFilter.GetPropertyExclude()).to_ulong();

	}

	//TODO:预留针对Property的查询过滤。

	//记录SQL日志
	C2C_WW_LOG_DEBUG("ExeSql Passed, Sql:%s", ssSql.str().c_str());

	IResultSet& oRs = oStorage.QueryForResultSet(ssSql.str());

	if (!oRs.IsReady()) //db操作错误
	{
		oRs.Close();
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_SELECT_FAILED, "ExeSql Failed, Sql:%s",
				ssSql.str().c_str());
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_SELECT_FAILED,
				"ExeSql Failed, OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				rCntlInfo.getOperatorUin(), strMachineKey.c_str(),
				strSource.c_str(), dwSceneId);
		C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
		return ERR_ERP_COMMON_DB_SELECT_FAILED;
	}

	if (!oRs.First() || oRs.GetRecordCount() == 0) //无记录
	{
		oRs.Close();
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_SELECT_FAILED, "ExeSql Failed, Sql:%s",
				ssSql.str().c_str());
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_QUERY_FAILED,
				"QuerySql not exist, " "OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				rCntlInfo.getOperatorUin(), strMachineKey.c_str(),
				strSource.c_str(), dwSceneId);
		C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
		return ERR_ERP_COMMON_DB_SELECT_FAILED;
	}

	//循环取数据
	do
	{
		erp::acaccount::ddo::CBankAccountDdo oBankAccountDdo;
		oBankAccountDdo.SetBankAccountSysNo(oRs.GetBigUInt("FBankAccountSysNo"),
				0);
		oBankAccountDdo.SetBankAccount(
				oRs.GetString("FBankAccount") ?
						oRs.GetString("FBankAccount") : "", 0);
		oBankAccountDdo.SetBankAccountName(
				oRs.GetString("FBankAccountName") ?
						oRs.GetString("FBankAccountName") : "", 0);
		oBankAccountDdo.SetBankType(
				oRs.GetString("FBankType") ? oRs.GetString("FBankType") : "",
				0);
		oBankAccountDdo.SetBranchBank(
				oRs.GetString("FBranchBank") ?
						oRs.GetString("FBranchBank") : "", 0);
		oBankAccountDdo.SetComment(
				oRs.GetString("FComment") ? oRs.GetString("FComment") : "", 0);
		oBankAccountDdo.SetModifierSysNo(oRs.GetBigUInt("FModifierSysNo"), 0);
		oBankAccountDdo.SetParentBankAccountSysNo(
				oRs.GetBigUInt("FParentBankAccountSysNo"), 0);
		oBankAccountDdo.SetProperty(oRs.GetUInt("FProperty"), 0);
		oBankAccountDdo.SetRowCreatDate(oRs.GetBigUInt("FRowCreatDate"), 0);
		oBankAccountDdo.SetRowModifyDate(oRs.GetBigUInt("FRowModifyDate"), 0);
		oBankAccountDdo.SetStatus(oRs.GetUInt("FStatus"), 0);

		vecBankAccount.push_back(oBankAccountDdo);
	} while (oRs.Next());
	oRs.Close();

	return iRetCode;
}

/**
 *
 *  写入&更新银行账户信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景id，必填   [in]
 *@param BankAccountDdo bankAccount: 银行账户信息ddo，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param uint64_t bankAccountSysNo: 银行账户SysNo 	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CACAccountDao::AddAndUpdateBankAccount(const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey, const std::string& strSource,
		uint32_t dwSceneId,
		const erp::acaccount::ddo::CBankAccountDdo& oBankAccount,
		const std::string& strInReserve, std::string& strErrmsg,
		uint64_t& ddwBankAccountSysNo, std::string& strOutReserve)
{
	int iRetCode = 0;
	//TODO:业务代码

	uint16_t iSetId = 0;
	m_dwOperatorUin = rCntlInfo.getOperatorUin();
	m_dwSceneId = dwSceneId;
	m_strMachineKey = strMachineKey;
	m_strSource = strSource;
	C2C_WW_LOG("GetAReq %s OpUin:%u MachineKey:%s Source:%s SceneId:%u",
			__FUNCTION__, m_dwOperatorUin, strMachineKey.c_str(),
			strSource.c_str(), dwSceneId);

	//打印性能日志的同时进行接口的itil上报
	C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG,__FUNCTION__,&iRetCode,&m_oAddAndUpdateBankAccount);

	//IdMaker
	if (oBankAccount.GetBankAccountSysNo() == 0)
	{
		//获取idmaker服务提供的sysno

		//申请的业务号
		uint32_t BizType = 234;

		//要申请的数量
		uint32_t ReqSize = 1;

		//服务实际返回给的数量
		uint32_t RespSize = 0;

		//服务返回的id的起始值,需要初始化
		uint64_t sysNo = 0;

		CIdMakerDaoStub4Web sysNoMaker;
		//调用了idmaker服务.并返回一个sysNo
		uint32_t idmakerResult = sysNoMaker.GetNeedIdsForU64(rCntlInfo, BizType,
				ReqSize, RespSize, sysNo);

		if (idmakerResult != 0 || sysNo == 0)
		{
			C2C_WW_LOG_ERR(ERR_ERP_YUN_MAKEID_FAILED,
					"Get make id failed, OpUin:%u MachineKey:%s Source:%s SceneId:%u, Result:%u, SysNo:%ld",
					rCntlInfo.getOperatorUin(), strMachineKey.c_str(),
					strSource.c_str(), dwSceneId, idmakerResult, sysNo);
			return ERR_ERP_YUN_MAKEID_FAILED;
		}

		//记录新增或者更新的银行账户SysNo
		ddwBankAccountSysNo = sysNo;
	}
	else
	{
		//记录新增或者更新的银行账户SysNo
		ddwBankAccountSysNo = oBankAccount.GetBankAccountSysNo();
	}

	c2cent::storage::CMySqlStorage oStorage(
			CDAL_SET->GetDBOperator(rCntlInfo.getCmdId(),
					rCntlInfo.getOperatorUin(), DB_ROLE_NAME_ACAccount, TABLE_NAME_BANKACCOUNT ,iSetId, true));

	std::stringstream sql;

	//插入或者更新一条记录
	sql << " INSERT INTO ";
	sql << " "
			<< CDAL_SET->GetTableName(iSetId, 0, DB_ROLE_NAME_ACAccount, TABLE_NAME_BANKACCOUNT).c_str();
	sql
			<< " (FBankAccountSysNo,FParentBankAccountSysNo,FBankAccount,FBankAccountName,FBranchBank,FBankType,";
	sql
			<< "FComment,FProperty,FStatus,FCreatorSysNo,FRowCreatDate,FModifierSysNo,FRowModifyDate) ";
	sql << " VALUES( ";

	sql << " " << ddwBankAccountSysNo << ", "; //bigint unsigned
	sql << " " << oBankAccount.GetParentBankAccountSysNo() << ", "; //bigint unsigned
	sql << "'" << oStorage.EscapeString(oBankAccount.GetBankAccount()) << "',"; //varchar 60
	sql << "'" << oStorage.EscapeString(oBankAccount.GetBankAccountName())
			<< "',"; //varchar 100
	sql << "'" << oStorage.EscapeString(oBankAccount.GetBranchBank()) << "',"; //varchar 100
	sql << "'" << oStorage.EscapeString(oBankAccount.GetBankType()) << "',"; //varchar 400

	sql << "'" << oStorage.EscapeString(oBankAccount.GetComment()) << "',"; //varchar 1000

	//属性
	sql << " "
			<< (oBankAccount.GetPropertyInclude() & ~oBankAccount.GetPropertyExclude()).to_ulong() << ", ";

	sql << " " << oBankAccount.GetStatus() << ", "; //int unsigned
	sql << " " << oBankAccount.GetCreatorSysNo() << ", "; //int unsigned
	sql << " " << "now(), "; //int unsigned
	sql << " " << oBankAccount.GetModifierSysNo() << ", "; //int unsigned
	sql << " " << "now() "; //int unsigned

	sql << " ) ON DUPLICATE KEY UPDATE ";

	if (oBankAccount.IsBankAccountSysNoSet())
	{
		sql << " FBankAccountSysNo=VALUES(FBankAccountSysNo), ";
	}
	if (oBankAccount.IsParentBankAccountSysNoSet())
	{
		sql << " FParentBankAccountSysNo=VALUES(FParentBankAccountSysNo), ";
	}
	if (oBankAccount.IsBankAccountSet())
	{
		sql << " FBankAccount=VALUES(FBankAccount), ";
	}
	if (oBankAccount.IsBankAccountNameSet())
	{
		sql << " FBankAccountName=VALUES(FBankAccountName), ";
	}
	if (oBankAccount.IsBranchBankSet())
	{
		sql << " FBranchBank=VALUES(FBranchBank), ";
	}
	if (oBankAccount.IsBankTypeSet())
	{
		sql << " FBankType=VALUES(FBankType), ";
	}

	if (oBankAccount.IsCommentSet())
	{
		sql << " FComment=VALUES(FComment), ";
	}

	//属性
	if (oBankAccount.IsPropertyExcludeSet()
			&& oBankAccount.IsPropertyIncludeSet())
	{
		sql << ",FProperty =" << "(FProperty |"
				<< oBankAccount.GetPropertyInclude() << ")&~" << oBankAccount.GetPropertyExclude().to_ulong();
	}

	if (oBankAccount.IsStatusSet())
	{
		sql << " FStatus=VALUES(FStatus), ";
	}
	if (oBankAccount.IsCreatorSysNoSet())
	{
		sql << " FCreatorSysNo=VALUES(FCreatorSysNo), ";
	}
	if (oBankAccount.IsRowCreatDateSet())
	{
		sql << " FRowCreatDate=VALUES(FRowCreatDate), ";
	}
	if (oBankAccount.IsModifierSysNoSet())
	{
		sql << " FModifierSysNo=VALUES(FModifierSysNo), ";
	}
	sql << " FRowModifyDate=now() ";

	//记录SQL日志
	C2C_WW_LOG_DEBUG("ExeSql Passed, Sql:%s", sql.str().c_str());

	iRetCode = oStorage.Update(sql.str());
	if (iRetCode != 0)
	{
		//错误日志
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_INSERT_FAILED, "ExeSql Failed, Sql:%s",
				sql.str().c_str());
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_INSERT_FAILED,
				"ExeSql Failed, OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				rCntlInfo.getOperatorUin(), strMachineKey.c_str(),
				strSource.c_str(), dwSceneId);
		C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);

		return ERR_ERP_COMMON_DB_INSERT_FAILED;
	}

	return iRetCode;
}

/**
 *
 *  逻辑删除银行账户信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景id，必填   [in]
 *@param uint64_t bankAccountSysNo: 银行账户SysNo  [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CACAccountDao::DeleteBankAccount(const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey, const std::string& strSource,
		uint32_t dwSceneId, uint64_t ddwBankAccountSysNo,
		const std::string& strInReserve, std::string& strErrmsg,
		std::string& strOutReserve)
{
	int iRetCode = 0;
	//TODO:业务代码
	uint16_t iSetId = 0;
	m_dwOperatorUin = rCntlInfo.getOperatorUin();
	m_dwSceneId = dwSceneId;
	m_strMachineKey = strMachineKey;
	m_strSource = strSource;
	C2C_WW_LOG("GetAReq %s OpUin:%u MachineKey:%s Source:%s SceneId:%u",
			__FUNCTION__, m_dwOperatorUin, strMachineKey.c_str(),
			strSource.c_str(), dwSceneId);

	//打印性能日志的同时进行接口的itil上报
	C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG,__FUNCTION__,&iRetCode,&m_oDeleteBankAccount);

	if (ddwBankAccountSysNo == 0)
	{
		return 0;
	}

	c2cent::storage::CMySqlStorage oStorage(
			CDAL_SET->GetDBOperator(rCntlInfo.getCmdId(),
					rCntlInfo.getOperatorUin(), DB_ROLE_NAME_ACAccount, TABLE_NAME_BANKACCOUNT,iSetId, true));

	std::stringstream sql;
	//将数据标识为逻辑删除状态
	sql << " UPDATE ";
	sql << " "
			<< CDAL_SET->GetTableName(iSetId, 0, DB_ROLE_NAME_ACAccount, TABLE_NAME_BANKACCOUNT).c_str();
	sql << " SET FStatus=0" << " WHERE ";
	sql << " FBankAccountSysNo= " << ddwBankAccountSysNo;

	iRetCode = oStorage.Update(sql.str());
	if (iRetCode != 0)
	{
		//错误日志
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_DELETE_FAILED, "ExeSql Failed, Sql:%s",
				sql.str().c_str());
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_INSERT_FAILED,
				"ExeSql Failed, OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				rCntlInfo.getOperatorUin(), strMachineKey.c_str(),
				strSource.c_str(), dwSceneId);
		C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);

		return ERR_ERP_COMMON_DB_INSERT_FAILED;
	}
	return iRetCode;
}

/**
 *
 *  写入&更新经营类会计项目信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景id，必填   [in]
 *@param ACItemsDdo aCItemsDdo: 经营类会计项目信息ddo，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param uint64_t aCItemsSysNo: 银行账户SysNo 	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CACAccountDao::AddAndUpdateACItems(const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey, const std::string& strSource,
		uint32_t dwSceneId, const erp::acaccount::ddo::CACItemsDdo& oACItemsDdo,
		const std::string& strInReserve, std::string& strErrmsg,
		uint64_t& ddwACItemsSysNo, std::string& strOutReserve)
{
	uint32_t dwRet = 0;
	//TODO:业务代码

	uint16_t wSetId = 0;
	m_dwOperatorUin = rCntlInfo.getOperatorUin();
	m_dwSceneId = dwSceneId;
	m_strMachineKey = strMachineKey;
	m_strSource = strSource;
	C2C_WW_LOG("GetAReq %s OpUin:%u MachineKey:%s Source:%s SceneId:%u",
			__FUNCTION__, m_dwOperatorUin, strMachineKey.c_str(),
			strSource.c_str(), dwSceneId);

	//打印性能日志的同时进行接口的itil上报
	C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG,__FUNCTION__,&dwRet,&m_oAddAndUpdateBankAccount);

	//IdMaker
	if (oACItemsDdo.GetACItemsSysNo() == 0)
	{
		//获取idmaker服务提供的sysno

		//申请的业务号
		uint32_t BizType = 237;

		//要申请的数量
		uint32_t ReqSize = 1;

		//服务实际返回给的数量
		uint32_t RespSize = 0;

		//服务返回的id的起始值,需要初始化
		uint64_t sysNo = 0;

		CIdMakerDaoStub4Web sysNoMaker;
		//调用了idmaker服务.并返回一个sysNo
		uint32_t idmakerResult = sysNoMaker.GetNeedIdsForU64(rCntlInfo, BizType,
				ReqSize, RespSize, sysNo);

		if (idmakerResult != 0 || sysNo == 0)
		{
			C2C_WW_LOG_ERR(ERR_ERP_YUN_MAKEID_FAILED,
					"Get make id failed, OpUin:%u MachineKey:%s Source:%s SceneId:%u, Result:%u, SysNo:%ld",
					rCntlInfo.getOperatorUin(), strMachineKey.c_str(),
					strSource.c_str(), dwSceneId, idmakerResult, sysNo);
			return ERR_ERP_YUN_MAKEID_FAILED;
		}

		//记录新增或者更新的银行账户SysNo
		ddwACItemsSysNo = sysNo;
	}
	else
	{
		//记录新增或者更新的银行账户SysNo
		ddwACItemsSysNo = oACItemsDdo.GetACItemsSysNo();
	}

	//定义SQL拼接变量
	std::stringstream ssSql;

	//打开数据库链接
	SQL_INSERT_TABLE(ssSql, wSetId, rCntlInfo.getOperatorUin(),
			DB_ROLE_NAME_ACAccount, TABLE_NAME_ACITEMS);
	SQL_SET_INT_FIELD_VALUE(ssSql, FACItemsSysNo, ddwACItemsSysNo); //会计项目信息SysNo
	SQL_SET_INT_FIELD(ssSql, ParentACItemsSysNo, oACItemsDdo); //父会计项目信息SysNo
	SQL_SET_STRING_FIELD(ssSql, FACItemsName, oACItemsDdo, m_oStorage); //项目名称
	SQL_SET_INT_FIELD(ssSql, ACItemsType, oACItemsDdo); //会计项目信息类型
	SQL_SET_STRING_FIELD(ssSql, Comment, oACItemsDdo, m_oStorage); //备注
	SQL_SET_PROPERTY_FIELD(ssSql, ACItemsProperty, oACItemsDdo); //会计项目信息属性
	SQL_SET_INT_FIELD(ssSql, ACItemsStatus, oACItemsDdo); //会计项目信息状态
	SQL_SET_INT_FIELD_VALUE(ssSql, CreatorSysNo, rCntlInfo.getOperatorUid()); //创建人SysNo
	SQL_SET_TIME_FIELD_NOW(ssSql, RowCreatDate); //创建时间
	SQL_SET_INT_FIELD_VALUE(ssSql, ModifierSysNo, rCntlInfo.getOperatorUid()); //编辑者SysNo
	SQL_SET_TIME_FIELD_NOW_END(ssSql, RowModifyDate); //编辑时间

	//执行Insert
	SQL_DUPLICATE_UPDATE(ssSql);

	SQL_SET_FIELD_BEFORE_VALUE(ssSql, ParentACItemsSysNo, oACItemsDdo); //父会计项目信息SysNo
	SQL_SET_FIELD_BEFORE_VALUE(ssSql, FACItemsName, oACItemsDdo); //项目名称
	SQL_SET_FIELD_BEFORE_VALUE(ssSql, ACItemsType, oACItemsDdo); //会计项目信息类型
	SQL_SET_FIELD_BEFORE_VALUE(ssSql, Comment, oACItemsDdo); //备注
	SQL_SET_PROPERTY_FIELD(ssSql, ACItemsProperty, oACItemsDdo); //会计项目信息属性
	SQL_SET_FIELD_BEFORE_VALUE(ssSql, ACItemsStatus, oACItemsDdo); //会计项目信息状态
	SQL_SET_INT_FIELD_VALUE(ssSql, ModifierSysNo, rCntlInfo.getOperatorUid()); //编辑者SysNo
	SQL_SET_TIME_FIELD_NOW_END(ssSql, RowModifyDate); //编辑时间

	//执行Update
	DB_UPDATE(m_oStorage, ssSql, dwRet, rCntlInfo, strMachineKey, strSource,
			dwSceneId);

	//记录SQL日志
	C2C_WW_LOG_DEBUG("ExeSql Passed, Sql:%s", ssSql.str().c_str());

	if (dwRet != 0)
	{
		//错误日志
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_INSERT_FAILED, "ExeSql Failed, Sql:%s",
				ssSql.str().c_str());
		C2C_WW_LOG_ERR(ERR_ERP_COMMON_DB_INSERT_FAILED,
				"ExeSql Failed, OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				rCntlInfo.getOperatorUin(), strMachineKey.c_str(),
				strSource.c_str(), dwSceneId);
		C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);

		return ERR_ERP_COMMON_DB_INSERT_FAILED;
	}

	return dwRet;
}

/**
 *
 *  逻辑删除经营类会计项目信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景id，必填   [in]
 *@param uint64_t ACItemsSysNo: 会计项目信息SysNo  [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CACAccountDao::DeleteACItems(const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey, const std::string& strSource,
		uint32_t dwSceneId, uint64_t ddwACItemsSysNo,
		const std::string& strInReserve, std::string& strErrmsg,
		std::string& strOutReserve)
{
	uint32_t dwRet = 0;
	//TODO:业务代码

	return dwRet;
}

/**
 *
 *  通过SysNos获取经营类会计项目信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景id，必填   [in]
 *@param Set sysNoList: 银行账户SysNo数组，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param Map aACItems: 经营类会计项目信息列表  	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CACAccountDao::GetACItemsBySysNos(const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey, const std::string& strSource,
		uint32_t dwSceneId, const std::set<uint64_t>& setSysNoList,
		const std::string& strInReserve, std::string& strErrmsg,
		std::map<uint64_t, erp::acaccount::ddo::CACItemsDdo>& mapAACItems,
		std::string& strOutReserve)
{
	uint32_t dwRet = 0;
	//TODO:业务代码

	return dwRet;
}

/**
 *
 *  Filter过滤获取经营类会计项目信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景id，必填   [in]
 *@param ACItemsFilterDdo bankAccountFilter: 过滤器，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param Vector aCItems: 经营类会计项目信息 列表 	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CACAccountDao::GetACItemsByFilter(const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey, const std::string& strSource,
		uint32_t dwSceneId,
		const erp::acaccount::ddo::CACItemsFilterDdo& oBankAccountFilter,
		const std::string& strInReserve, std::string& strErrmsg,
		std::vector<erp::acaccount::ddo::CACItemsDdo>& vecACItems,
		std::string& strOutReserve)
{
	uint32_t dwRet = 0;
	//TODO:业务代码

	return dwRet;
}
